import numpy as np
from rag_test.pingan.pingan_text_embedding import text_embeddings  # 复用之前的向量化函数
from rag_pipeline import rag_pipeline  # 复用完整RAG流程


def evaluate_retrieval_relevance(questions, search_results):
    """
    评估检索相关性（自动计算相似度）

    参数:
        questions: 问题列表
        search_results: 每个问题对应的检索结果

    返回:
        平均相似度分数（0-1之间）
    """
    similarities = []
    for i, question in enumerate(questions):
        # 1. 计算问题的向量
        question_emb = text_embeddings(question)[0]

        # 2. 计算每个检索结果的向量并求相似度
        for res in search_results[i]:
            res_emb = text_embeddings(res["text"])[0]

            # 计算余弦相似度（值越接近1越相关）
            similarity = np.dot(question_emb, res_emb) / (
                    np.linalg.norm(question_emb) * np.linalg.norm(res_emb)
            )
            similarities.append(similarity)

    # 计算平均相似度
    avg_similarity = np.mean(similarities)
    print(f"检索平均相似度：{avg_similarity:.2f}（0-1，越高越好）")
    return avg_similarity


def evaluate_answer_accuracy(answers, ground_truths):
    """
    评估答案准确性（简单文本匹配）

    参数:
        answers: 系统生成的答案列表
        ground_truths: 标准答案列表

    返回:
        准确率（0-1之间）
    """
    correct = 0
    for ans, truth in zip(answers, ground_truths):
        # 简单判断：答案是否包含标准答案的核心词
        # （实际应用中可更复杂，这里适合小白入门）
        truth_keywords = set(truth.split())
        ans_keywords = set(ans.split())
        overlap = len(truth_keywords & ans_keywords) / len(truth_keywords)

        if overlap > 0.6:  # 重叠率超过60%认为准确
            correct += 1

    accuracy = correct / len(answers)
    print(f"答案准确率：{accuracy:.2f}（0-1，越高越好）")
    return accuracy


def run_evaluation(test_questions, ground_truths):
    """
    完整评估流程

    参数:
        test_questions: 测试问题列表
        ground_truths: 对应的标准答案列表
    """
    # 1. 收集系统输出
    system_answers = []
    search_results = []
    for question in test_questions:
        # 获取答案
        answer = rag_pipeline(question)
        system_answers.append(answer)

        # 获取检索结果（需要稍微修改hybrid_search函数使其能返回结果）
        from hybrid_search import hybrid_search
        results = hybrid_search(question)
        search_results.append(results)

    # 2. 评估检索相关性
    evaluate_retrieval_relevance(test_questions, search_results)

    # 3. 评估答案准确性
    evaluate_answer_accuracy(system_answers, ground_truths)


# 测试评估代码
if __name__ == "__main__":
    # 1. 准备测试数据（保险手册相关问题和标准答案）
    test_questions = [
        "平安福2024版的保障范围是什么？",
        "平安福2024版的投保年龄限制是多少？"
    ]

    # 标准答案（根据手册内容编写）
    ground_truths = [
        "平安福2024版主险为终身寿险，附加险涵盖120种重大疾病、20种中症、40种轻症，包含身故/全残保障。",
        "平安福2024版的投保年龄为28天-65周岁，续保可至100周岁。"
    ]

    # 2. 运行评估
    run_evaluation(test_questions, ground_truths)
